

import React, { Component } from 'react';
import './index.css';
import * as THREE from 'three';    //引入three基础相关的所有模块
import * as dat from 'dat.gui'; 
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';  // 控制器：鼠标控制旋转
import { Lut } from 'three/examples/jsm/math/Lut.js';  // 颜色条

 
class Three1 extends Component {
    constructor(props) {
        super(props);
        this.state = {  };
    }
    
  
    initThree = () => {   // 初始化，准备数据  四大组件：场景、相机、渲染器、几何体

        let container;

        let perpCamera, orthoCamera, renderer, lut;

        let mesh, sprite;
        let scene, uiScene;

        let params;
        container = document.getElementById( 'canvas-frame' );

				scene = new THREE.Scene();
				scene.background = new THREE.Color( 0xffffff );

				uiScene = new THREE.Scene();

				lut = new Lut();

				const width = window.innerWidth;
				const height = window.innerHeight;

				perpCamera = new THREE.PerspectiveCamera( 60, width / height, 1, 100 );
				perpCamera.position.set( 0, 0, 10 );
				scene.add( perpCamera );

				orthoCamera = new THREE.OrthographicCamera( - 1, 1, 1, - 1, 1, 2 );
				orthoCamera.position.set( 0.5, 0, 1 );

				sprite = new THREE.Sprite( new THREE.SpriteMaterial( {
					map: new THREE.CanvasTexture( lut.createCanvas() )
				} ) );
				sprite.scale.x = 0.125;
				uiScene.add( sprite );

				mesh = new THREE.Mesh( undefined, new THREE.MeshLambertMaterial( {
					side: THREE.DoubleSide,
					color: 0xF5F5F5,
					vertexColors: true
				} ) );
				scene.add( mesh );

				params	= {
					colorMap: 'rainbow',
				};
				loadModel( );

				const pointLight = new THREE.PointLight( 0xffffff, 1 );
				perpCamera.add( pointLight );

				renderer = new THREE.WebGLRenderer( { antialias: true } );
				renderer.autoClear = false;
				renderer.setPixelRatio( window.devicePixelRatio );
				renderer.setSize( width, height );
				container.appendChild( renderer.domElement );

				window.addEventListener( 'resize', onWindowResize, false );

				const controls = new OrbitControls( perpCamera, renderer.domElement );
				controls.addEventListener( 'change', render );

				var gui = new dat.GUI();

				gui.add( params, 'colorMap', [ 'rainbow', 'cooltowarm', 'blackbody', 'grayscale' ] ).onChange( function () {

					updateColors();
					render();

                } );
                

                function onWindowResize() {

                    const width = window.innerWidth;
                    const height = window.innerHeight;
    
                    perpCamera.aspect = width / height;
                    perpCamera.updateProjectionMatrix();
    
                    renderer.setSize( width, height );
                    render();
    
                }
    
                function render() {
    
                    renderer.clear();
                    renderer.render( scene, perpCamera );
                    renderer.render( uiScene, orthoCamera );
    
                }
    
                function loadModel( ) {
    
                    const loader = new THREE.BufferGeometryLoader();
                    loader.load( 'models/json/pressure.json', function ( geometry ) {
    
                        geometry.center();
                        geometry.computeVertexNormals();
    
                        // default color attribute
                        const colors = [];
    
                        for ( let i = 0, n = geometry.attributes.position.count; i < n; ++ i ) {
    
                            colors.push( 1, 1, 1 );
    
                        }
    
                        geometry.setAttribute( 'color', new THREE.Float32BufferAttribute( colors, 3 ) );
    
                        mesh.geometry = geometry;
                        updateColors();
    
                        render();
    
                    } );
    
                }
    
                function updateColors() {
    
                    lut.setColorMap( params.colorMap );
    
                    lut.setMax( 2000 );
                    lut.setMin( 0 );
    
                    const geometry = mesh.geometry;
                    const pressures = geometry.attributes.pressure;
                    const colors = geometry.attributes.color;
    
                    for ( let i = 0; i < pressures.array.length; i ++ ) {
    
                        const colorValue = pressures.array[ i ];
    
                        const color = lut.getColor( colorValue );
    
                        if ( color === undefined ) {
    
                            console.log( 'Unable to determine color for value:', colorValue );
    
                        } else {
    
                            colors.setXYZ( i, color.r, color.g, color.b );
    
                        }
    
                    }
    
                    colors.needsUpdate = true;
    
                    const map = sprite.material.map;
                    lut.updateCanvas( map.image );
                    map.needsUpdate = true;
    
                }

    }
 
    /**
     * 开始Three
     *
     * @memberof ThreeBim
     */
    componentDidMount(){
        this.initThree();
    }
    render() {
        return (
          <div id='canvas-frame'></div>
        );
    }
}
 
export default Three1;